using System.Collections.Generic;
using FixMath;
using UniFramework.Actor;
using UnityEngine;

namespace UniFramework.Battle
{
	public class BulletSystem : MonoBehaviour
	{
		private List<LogicBullet> _bulletList = new List<LogicBullet>();

		public void OnLogicFrameUpdate()
		{
			if (_bulletList != null && _bulletList.Count > 0)
			{
				FixInt timePassed = LogicFrameConfig.logicFrameIntervalFixInt;
				LogicActor[] actors = GameObject.FindObjectsByType<LogicActor>(FindObjectsSortMode.None);
				List<LogicBullet> needRemoveBulletList = new List<LogicBullet>();
				foreach (var bullet in _bulletList)
				{
					if (bullet.BulletObj.hitCnt >= bullet.BulletObj.config.cnaHitCnt) continue;
					int index = 0;
					var hitRecordList = bullet.HitRecordList;
					//处理下击中记录，更新击中时间，超过时间的就移除
					while (index < hitRecordList.Count)
					{
						hitRecordList[index].timeToCanHit -= timePassed;
						if (hitRecordList[index].timeToCanHit <= 0) hitRecordList.RemoveAt(index);
						else ++index;
					}


					//子弹去移动
					bullet.Move();

					//子弹碰撞处理,更新创建出来的多久后能碰撞的时间，更新玩家碰撞
					if (bullet.BulletObj.canHitDelay > 0)
					{
						bullet.BulletObj.canHitDelay -= timePassed;
					}
					else
					{
						FixInt r = bullet.BulletObj.config.radius;
						if (actors != null && actors.Length > 0)
						{
							foreach (var actor in actors)
							{
								//玩家死了或者子弹不能击中当前玩家
								if (actor.isDead || bullet.CanHit(actor) == false) continue;
								FixIntVector3 playPos = new FixIntVector3(actor.transform.position);
								FixIntVector3 bulletPos = new FixIntVector3(bullet.transform.position);
								FixInt dis = FixIntVector3.Distance(playPos, bulletPos);
								//命中了,还有攻击次数就不销毁并添加击中记录，否则就销毁
								if (dis < r && bullet.CanHit(actor))
								{
									bullet.BulletObj.hitCnt += 1;
									bullet.BulletObj.config.onHit?.Invoke(bullet, actor);
									if (bullet.BulletObj.hitCnt >= bullet.BulletObj.config.cnaHitCnt)
										needRemoveBulletList.Add(bullet);
									else bullet.AddHitRecord(actor);
									//为了解耦，这个地方可以放到OnHit去做成一个受击函数
									var damageSystem = GameObject.FindAnyObjectByType<DamageSystem>();
									Damage damage = new Damage()
									{
										damageValue = bullet.BulletObj.config.deleteHp
									};
									damageSystem.DoDamage(null, actor, damage);
								}
							}
						}
					}

					//更新子弹时间
					bullet.BulletObj.duration -= timePassed;
					bullet.BulletObj.timeElapsed -= timePassed;
					if (bullet.BulletObj.duration <= 0) needRemoveBulletList.Add(bullet);
				}

				//移除需要移除的子弹
				foreach (var bullet in needRemoveBulletList) RemoveBullet(bullet);
				needRemoveBulletList.Clear();
				needRemoveBulletList = null;
			}
		}

		/// <summary>
		/// 这里后续修改为对象池
		/// </summary>
		/// <param name="bulletObj"></param>
		public LogicBullet CreateBullet(BulletObj bulletObj)
		{
			GameObject bullet = GameObject.Instantiate(bulletObj.config.bulletPrefab);
			bullet.transform.position = bulletObj.firePos.ToVector3();
			bullet.transform.forward = bulletObj.fireAngle.ToVector3();
			var logicBullet = bullet.AddComponent<LogicBullet>();
			logicBullet.InitData(bulletObj);
			logicBullet.OnCreate();
			_bulletList.Add(logicBullet);
			bulletObj.config.onCreate?.Invoke(logicBullet);
			return logicBullet;
		}

		/// <summary>
		/// 移除子弹
		/// </summary>
		/// <param name="bullet"></param>
		public void RemoveBullet(LogicBullet bullet)
		{
			if (bullet != null)
			{
				bullet.BulletObj.config.onRemoved?.Invoke(bullet);
				GameObject.Destroy(bullet.gameObject);
				bullet.OnDie();
				_bulletList.Remove(bullet);
			}
		}
	}
}